home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / misc / dctvdev3.lzh / example / dctvgrad.c next >
C/C++ Source or Header  |  1992-08-12  |  8KB  |  267 lines

  1. /**********************************************************************
  2. *
  3. *   dctvgrad.c - Render a 24-bit RGB gradient visible on DCTV.
  4. *
  5. *   Copyright (C) 1991, 1992 Digital Creations, Inc.
  6. *
  7. *   DESCRIPTION
  8. *       This example demonstrates how to call dctv.library to generate a
  9. *       DCTV frame by suppling lines of 24-bit RGB data (in this case a
  10. *       multi-point gradient).  The finished BitMap can then be written
  11. *       to an ILBM file.
  12. *
  13. *       Program runs under Amiga OS v1.3 and higher.
  14. *
  15. *   USAGE
  16. *       dctvgrad <width> <height> <depth>
  17. *           width  - screen width (640..736)
  18. *           height - screen height (200..241, 400..482)
  19. *           depth  - screen depth (3..4)
  20. *
  21. *       Terminate with Control+C.
  22. *
  23. *   COMPILATION
  24. *       SAS/C:      (v5.10 or higher.  Regular of ANSI libs)
  25. *           lc -L+dctv.lib dctvgrad
  26. *
  27. *       Aztec C:    (v5.0a or higher)
  28. *           cc dctvgrad [works w/ either 16 or 32 bit int's]
  29. *           ln dctvgrad.o +l dctv.lib -lc
  30. *
  31. *   REQUIREMENTS
  32. *       . Aztec C 5.0 or SAS/C 5.10.
  33. *       . v37.4 or higher Amiga include files.
  34. *       . OS #pragmas created for your compiler in the pragmas
  35. *         directory of your include path.
  36. *
  37. **********************************************************************/
  38.  
  39. #include <dos/dos.h>
  40. #include <intuition/screens.h>
  41. #include <libraries/dctv.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include <string.h>
  45.  
  46. #include <clib/dctv_protos.h>
  47. #include <clib/exec_protos.h>
  48. #include <clib/graphics_protos.h>
  49. #include <clib/intuition_protos.h>
  50.  
  51. #include <pragmas/dctv_pragmas.h>
  52. #include <pragmas/exec_pragmas.h>
  53. #include <pragmas/graphics_pragmas.h>
  54. #include <pragmas/intuition_pragmas.h>
  55.  
  56.  
  57. /* -------------------- misc defines */
  58.  
  59. #define DCTVLIB_Version 3
  60.  
  61.  
  62. /* -------------------- data */
  63.  
  64. struct Library *DCTVBase, *GfxBase, *IntuitionBase;
  65.  
  66.  
  67. /* -------------------- local functions */
  68.  
  69.     /* screen processor */
  70. void doscreen (short width, short height, short depth);
  71.  
  72.     /* gradient functions */
  73. void initgrad (struct DCTVCvtHandle *);
  74. void rendergradline (struct DCTVCvtHandle *);
  75.  
  76.  
  77. /* -------------------- main() */
  78.  
  79. #if AZTEC_C
  80.   void _wb_parse (void) {}      /* stub out wb window parser */
  81. #endif
  82.  
  83. #if __SASC  /* suppress normal Ctrl-C processing (SAS/C) */
  84.   void __chkabort (void) {}
  85.   void chkabort (void) {}
  86. #endif
  87.  
  88. int main (int argc, char **argv)
  89. {
  90.     if (argc < 4) goto clean;
  91.  
  92.   #if AZTEC_C           /* suppress normal Ctrl-C processing (Aztec C) */
  93.     {
  94.         extern int Enable_Abort;
  95.         Enable_Abort = 0;
  96.     }
  97.   #endif
  98.  
  99.     if (!(IntuitionBase = OpenLibrary ("intuition.library", LIBRARY_MINIMUM))) goto clean;
  100.     if (!(GfxBase = OpenLibrary ("graphics.library", LIBRARY_MINIMUM))) goto clean;
  101.     if (!(DCTVBase = OpenLibrary ("dctv.library", DCTVLIB_Version))) {
  102.         printf ("requires dctv.library v%d\n", DCTVLIB_Version);
  103.         goto clean;
  104.     }
  105.  
  106.     doscreen (atoi(argv[1]), atoi(argv[2]), atoi(argv[3]));
  107.  
  108. clean:
  109.     if (DCTVBase) CloseLibrary (DCTVBase);
  110.     if (GfxBase) CloseLibrary (GfxBase);
  111.     if (IntuitionBase) CloseLibrary (IntuitionBase);
  112.     return 0;
  113. }
  114.  
  115.  
  116. /* -------------------- doscreen() */
  117.  
  118. struct Screen *openscreen (short width, short height, short depth);
  119. struct DCTVCvtHandle *alloccvt (struct Screen *);
  120.  
  121. void doscreen (short width, short height, short depth)
  122. {
  123.     struct Screen *screen = NULL;
  124.     struct DCTVCvtHandle *cvt = NULL;
  125.  
  126.         /* Open a screen (also conveniently creates a BitMap for use with dctv.library). */
  127.     if (!(screen = openscreen (width, height, depth))) goto clean;
  128.  
  129.         /* Allocate DCTV conversion environment. */
  130.     if (!(cvt = alloccvt (screen))) goto clean;
  131.  
  132.         /* Initialize Screen colors and format BitMap for a black DCTV display. */
  133.     LoadRGB4 (&screen->ViewPort, cvt->ColorTable, cvt->NColors);
  134.     FormatDCTV (cvt);
  135.  
  136.         /* Make a frame. */
  137.     initgrad (cvt);                 /* Init gradient data. */
  138.  
  139.         /*
  140.             Line rendering loop.
  141.  
  142.             Loop until all Destination lines have been converted
  143.             (indicated by DstLineNum >= height).
  144.  
  145.             Because the filter process introduces an N-line delay
  146.             between source and destination lines, you must call
  147.             CvtDCTVLine() until all the destination lines have been
  148.             converted.  That means the code in this loop will be
  149.             executed (height + NDelayLines) times.
  150.  
  151.             Your rendering code should use SrcLineNum to indicate which
  152.             line to render.  CvtDCTVLine() ignores the RGB line buffer for
  153.             SrcLineNum values outside the range of the ImageBounds
  154.             rectangle.  SrcLineNum is in the range of
  155.             0 <= SrcLineNum < Height+NDelayLines before each call; avoid
  156.             overindex your rendering code.
  157.         */
  158.     while (cvt->DstLineNum < cvt->Height) {
  159.  
  160.                                     /* Abort on Ctrl-C. */
  161.         if (SetSignal (0, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) goto clean;
  162.  
  163.         rendergradline (cvt);       /* Render a line of the gradient to
  164.                                        DCTVCvtHandle RGB line buffer.
  165.                                        This function is smart enough to
  166.                                        handle line #'s out of range. */
  167.  
  168.         CvtDCTVLine (cvt);          /* Convert the line in the line buffer to
  169.                                        DCTV display data. Results in rendering
  170.                                        a line of the BitMap. */
  171.     }
  172.  
  173.     Wait (SIGBREAKF_CTRL_C);        /* Wait until user types Control+C
  174.                                        into shell window before quitting. */
  175.  
  176. clean:
  177.     if (cvt) FreeDCTVCvt (cvt);
  178.     if (screen) CloseScreen (screen);
  179. }
  180.  
  181. struct Screen *openscreen (short width, short height, short depth)
  182. {
  183.     static struct NewScreen newscreen = {
  184.         0, 0, 0, 0, 0,
  185.         -1, -1,
  186.         0,
  187.         CUSTOMSCREEN | SCREENQUIET,
  188.         NULL,
  189.         "dctvgrad",
  190.         NULL,
  191.         NULL
  192.     };
  193.     struct Screen *screen;
  194.  
  195.     newscreen.Width = width + 15 & ~15;     /* pad width to next multiple of 16 */
  196.     newscreen.Height = height;
  197.     newscreen.Depth = depth;
  198.     newscreen.ViewModes = height > 350 ? HIRESLACE_KEY : HIRES_KEY;
  199.  
  200.     if (!(screen = OpenScreen (&newscreen))) {
  201.         puts ("OpenScreen failed\n");
  202.     }
  203.  
  204.     return screen;
  205. }
  206.  
  207. struct DCTVCvtHandle *alloccvt (struct Screen *screen)
  208. {
  209.     ULONG flags = 0;
  210.     struct DCTVCvtHandle *cvt;
  211.     ULONG errcode;
  212.  
  213.     if (screen->ViewPort.Modes & LACE) flags |= DCTVCVTF_Lace;
  214.     if (!(cvt = AllocDCTVCvtTags ( screen->RastPort.BitMap,
  215.                                    DCTVCVTA_Type,       (ULONG)DCTVCVTT_RGBtoDCTV,
  216.                                    DCTVCVTA_Width,      (ULONG)screen->Width,
  217.                                    DCTVCVTA_Height,     (ULONG)screen->Height,
  218.                                    DCTVCVTA_Flags,      (ULONG)flags,
  219.                                    DCTVCVTA_ErrorCode,  &errcode,
  220.                                    TAG_END ))) {
  221.         printf ("AllocDCTVCvtTags failed %lu\n", errcode);
  222.     }
  223.  
  224.     return cvt;
  225. }
  226.  
  227.  
  228. /* -------------------- 24-bit RGB gradient functions */
  229.  
  230. #define gcent(m,l)  (((m)-(l)) / 2)         /* centering macro */
  231.  
  232. void initgrad (struct DCTVCvtHandle *cvt)
  233. {
  234.     short bufwidth   = cvt->Width;
  235.     short imagewidth = cvt->ImageBounds.MaxX - cvt->ImageBounds.MinX + 1;
  236.     short i;
  237.  
  238.         /* init line to black */
  239.     memset (cvt->Red, 0, bufwidth);
  240.     memset (cvt->Green, 0, bufwidth);
  241.     memset (cvt->Blue, 0, bufwidth);
  242.  
  243.         /* ramp red horizontally */
  244.     for (i=0; i < imagewidth; i++)
  245.         cvt->Red [i+cvt->ImageBounds.MinX] = (ULONG)i * 255 / imagewidth;
  246. }
  247.  
  248. void rendergradline (struct DCTVCvtHandle *cvt)
  249. {
  250.     short imagewidth  = cvt->ImageBounds.MaxX - cvt->ImageBounds.MinX + 1;
  251.     short imageheight = cvt->ImageBounds.MaxY - cvt->ImageBounds.MinY + 1;
  252.     short y = cvt->SrcLineNum - cvt->ImageBounds.MinY;
  253.     short bluewidth;
  254.     UBYTE greenval;
  255.  
  256.     if (y >= 0 && y < imageheight) {
  257.             /* constant green component for line */
  258.         greenval = (long)y * 255 / imageheight;
  259.         memset (cvt->Green + cvt->ImageBounds.MinX, greenval, imagewidth);
  260.  
  261.             /* reverse wedge blue component */
  262.         bluewidth = (long)(imageheight - y) * imagewidth / imageheight;
  263.         if (bluewidth > 0)
  264.             memset (cvt->Blue + gcent (imagewidth, bluewidth) + cvt->ImageBounds.MinX, 255-greenval, bluewidth);
  265.     }
  266. }
  267.